package controllers

import (
	"fmt"
	"github.com/goravel/framework/contracts/database/orm"
	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/support/carbon"
	"goravel/app/models"
)

type AuthController struct {
	//Dependent services
}

func NewAuthController() *AuthController {
	return &AuthController{
		//Inject services
	}
}

func (r *AuthController) Login(ctx http.Context) http.Response {
	validator, err := facades.Validation().Make(map[string]any{
		"mobile":   ctx.Request().Input("mobile", ""),
		"password": ctx.Request().Input("password", ""),
	}, map[string]string{
		"mobile":   "required",
		"password": "required",
	})

	if validator.Fails() {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": validator.Errors().All(),
		})
	}
	var user models.User
	err = validator.Bind(&user)
	if err != nil {
		return ctx.Response().Status(http.StatusUnprocessableEntity).Json(http.Json{
			"message": "参数错误",
		})
	}
	//	查询user是否存在
	user_exist := models.User{}
	facades.Orm().Query().Where("mobile = ?", user.Mobile).With("Configurations").With("Refillcards").First(&user_exist)
	if user_exist.ID == 0 {
		return ctx.Response().Status(http.StatusUnprocessableEntity).Json(http.Json{
			"message": "用户不存在",
		})

	} else {
		//	验证密码是否正确
		if !facades.Hash().Check(user.Password, user_exist.Password) {
			return ctx.Response().Status(http.StatusUnprocessableEntity).Json(http.Json{
				"message": "密码错误",
			})
		} else {
			//	生成token
			token, err1 := facades.Auth().Login(ctx, &user_exist)
			if err1 != nil {
				return ctx.Response().Status(http.StatusUnprocessableEntity).Json(http.Json{
					"message": "token生成失败",
				})
			}

			//
			var log models.Log
			log.UserId = user_exist.ID
			log.Type = "登录成功"
			ip := ctx.Request().Ip()
			time := carbon.Now().ToDateTimeString()
			log.Content = fmt.Sprintf("用户%s登录成功,ip地址：%s，时间：%s", user_exist.Mobile, ip, time)
			facades.Orm().Query().Create(&log)
			return ctx.Response().Status(http.StatusOK).Json(http.Json{
				"message": "登录成功",
				"data": struct {
					Token string      `json:"token"`
					User  models.User `json:"user"`
				}{
					Token: token,
					User:  user_exist,
				},
			})
		}
	}
}

func (r *AuthController) Logout(ctx http.Context) http.Response {
	err := facades.Auth().Logout(ctx)
	if err != nil {
		return ctx.Response().Status(http.StatusUnprocessableEntity).Json(http.Json{
			"message": "退出失败",
		})
	}
	return ctx.Response().Status(http.StatusOK).Json(http.Json{
		"message": "退出成功",
	})
}

// 注册
func (r *AuthController) Register(ctx http.Context) http.Response {
	type UserForm struct {
		Mobile   string `json:"mobile"`
		Password string `json:"password"`
		Secret   string `json:"secret"`
	}

	var userForm UserForm
	err := ctx.Request().Bind(&userForm)
	if err != nil {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "参数错误",
		})
	}
	var user models.User
	user.Mobile = userForm.Mobile
	facades.Orm().Query().Where("mobile = ?", user.Mobile).First(&user)
	if user.ID != 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "用户已存在",
		})
	}
	var refillcard models.Refillcard
	facades.Orm().Query().Where("secret = ?", userForm.Secret).First(&refillcard)
	if refillcard.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "充值卡不存在",
		})
	}
	if refillcard.State == 1 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "充值卡已使用",
		})
	}
	errT := facades.Orm().Transaction(func(tx orm.Transaction) error {
		//创建用户
		user.Password, _ = facades.Hash().Make(userForm.Password)
		//判断卡的类型，设置过期时间
		switch refillcard.Unit {
		case "day":
			user.ExpireTime = carbon.NewDateTime(carbon.Now().AddDay())
		case "week":
			user.ExpireTime = carbon.NewDateTime(carbon.Now().AddWeek())
		case "month":
			user.ExpireTime = carbon.NewDateTime(carbon.Now().AddMonth())
		case "half_year":
			user.ExpireTime = carbon.NewDateTime(carbon.Now().AddQuarters(2))
		case "year":
			user.ExpireTime = carbon.NewDateTime(carbon.Now().AddYear())
		}

		if err1 := tx.Create(&user); err1 != nil {
			return err1
		}
		refillcard.State = 1
		refillcard.UserName = user.Mobile

		//关联创建
		tx.Model(&user).Association("Refillcards").Append([]*models.Refillcard{&refillcard})
		var order models.Order
		//202312121841223的形式
		order.OrderNo = "CZ" + carbon.Now().Format("YmdHis")
		order.UserID = user.ID
		order.RefillcardID = refillcard.ID
		order.RefillcardTxt = fmt.Sprintf("账户：%s,消费充值卡，卡类：%s,卡号：%d，卡密：%s", user.Mobile, refillcard.Unit, refillcard.ID, refillcard.Secret)
		if err3 := tx.Create(&order); err3 != nil {
			return err3
		}
		//关联保存
		return tx.Model(&user).Association("Refillcards").Append([]*models.Refillcard{&refillcard})
	})
	if errT != nil {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "注册失败，请联系管理员！",
		})
	}
	facades.Orm().Query().Update(&refillcard)
	return ctx.Response().Status(http.StatusOK).Json(http.Json{
		"message": "注册成功",
	})
}

// 充值Charge
func (r *AuthController) Charge(ctx http.Context) http.Response {
	type UserForm struct {
		Mobile string `json:"mobile"`
		Secret string `json:"secret"`
	}
	var user models.User
	var userForm UserForm
	err := ctx.Request().Bind(&userForm)
	if err != nil {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "参数错误",
		})
	}
	facades.Orm().Query().Where("mobile = ?", userForm.Mobile).First(&user)
	if user.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "用户不存在",
		})
	}
	var refillcard models.Refillcard
	facades.Orm().Query().Where("secret = ?", userForm.Secret).First(&refillcard)
	if refillcard.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "充值卡不存在",
		})
	}
	if refillcard.State == 1 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "充值卡已使用",
		})
	}
	switch refillcard.Unit {
	case "day":
		user.ExpireTime = carbon.NewDateTime(carbon.Parse(user.ExpireTime.String()).AddDay())
	case "week":
		user.ExpireTime = carbon.NewDateTime(carbon.Parse(user.ExpireTime.String()).AddWeek())
	case "month":
		user.ExpireTime = carbon.NewDateTime(carbon.Parse(user.ExpireTime.String()).AddMonth())
	case "half_year":
		user.ExpireTime = carbon.NewDateTime(carbon.Parse(user.ExpireTime.String()).AddQuarters(2))
	case "year":
		user.ExpireTime = carbon.NewDateTime(carbon.Parse(user.ExpireTime.String()).AddYear())
	}
	//开启事务
	errT := facades.Orm().Transaction(func(tx orm.Transaction) error {
		refillcard.State = 1
		refillcard.UserName = user.Mobile
		if _, err2 := tx.Update(&user); err2 != nil {
			return err2
		}
		if _, err1 := tx.Update(&refillcard); err1 != nil {
			return err1
		}
		var order models.Order
		//202312121841223的形式
		order.OrderNo = "CZ" + carbon.Now().Format("YmdHis")
		order.UserID = user.ID
		order.RefillcardID = refillcard.ID
		order.RefillcardTxt = fmt.Sprintf("账户：%s,消费充值卡，卡类：%s,卡号：%d，卡密：%s", user.Mobile, refillcard.Unit, refillcard.ID, refillcard.Secret)
		if err3 := tx.Create(&order); err3 != nil {
			return err3
		}
		//关联保存
		return tx.Model(&user).Association("Refillcards").Append([]*models.Refillcard{&refillcard})
	})
	if errT != nil {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "充值失败，请联系管理员！",
		})
	}
	return ctx.Response().Status(http.StatusOK).Json(http.Json{
		"message": "充值成功",
	})
}
